package cn.yr.clock.handler;


import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.yr.clock.domain.enmu.EngineEnum;
import cn.yr.clock.domain.entity.Engine;
import cn.yr.clock.domain.entity.Record;
import cn.yr.clock.service.EngineService;
import cn.yr.clock.service.RecordService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class EngineHandler {

    @Autowired
    private RecordService recordService;
    @Autowired
    private EngineService engineService;

    private TimedCache<String, Integer> timedCache = CacheUtil.newTimedCache(1000 * 60 * 60 * 12);

    @Value("${cycleDayNum:42}")
    private Integer cycleDayNum;

    public void clearCache() {
        timedCache.clear();
    }

    /**
     * 累计打卡数
     *
     * @param userId
     * @return
     */
    public Integer sumClock(Long userId) {
        Integer sum = timedCache.get(userId+":sum");
        if (ObjectUtil.isNotNull(sum)) {
            return sum;
        }
        DateTime endTime = DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), 1));
        long between = DateUtil.between(endTime, new Date(), DateUnit.MINUTE);
        sum = recordService.sumRecordByUserId(userId);
        timedCache.put(userId+":sum", sum, 1000 * 60 * between);
        return sum;
    }

    /**
     * 连续打卡数
     *
     * @param userId
     * @return
     */
    public Integer continuousClock(Long userId) {
        Integer continuous = timedCache.get(userId+":continuous");
        if (ObjectUtil.isNotNull(continuous)) {
            return continuous;
        }
        DateTime endTime = DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), 1));
        long between = DateUtil.between(endTime, new Date(), DateUnit.MINUTE);
       // Record lastRecord = recordService.getLastRecord(userId);
        continuous = recordService.selectContinuous(userId);
        /*if(ObjectUtil.isNull(lastRecord)){
            continuous = 0;
        }else {
            continuous = lastRecord.getContinuousNum();
        }*/
        timedCache.put(userId+":continuous", continuous, 1000 * 60 * between);
        return continuous;
    }

    /**
     * 循环打卡数
     *
     * @param userId
     * @return
     */
    public Integer cycleNum(Long userId) {
        Integer cycle = timedCache.get(userId+":cycle");
        if (ObjectUtil.isNotNull(cycle)) {
            return cycle;
        }
        DateTime endTime = DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), 1));
        long between = DateUtil.between(endTime, new Date(), DateUnit.MINUTE);
        cycle = sumClock(userId) % cycleDayNum;
        timedCache.put(userId+":cycle", cycle, 1000 * 60 * between);
        return cycle;
    }

    /**
     * 是否达到累计打卡奖励
     *
     * @param userId
     * @return
     */
    public Engine isSumClock(Long userId) {
        Integer num = sumClock(userId);
        QueryWrapper<Engine> wrapper = new QueryWrapper<>();
        wrapper.eq("num", num);
        wrapper.eq("engine_type", EngineEnum.Sum.getType());
        return engineService.getOne(wrapper, false);
    }

    /**
     * 是否达到连续打卡奖励
     *
     * @param userId
     * @return
     */

    public Engine isContinuousClock(Long userId) {
        Integer num = continuousClock(userId);
        QueryWrapper<Engine> wrapper = new QueryWrapper<>();
        wrapper.eq("num", num);
        wrapper.eq("engine_type", EngineEnum.Continuous.getType());
        return engineService.getOne(wrapper, false);
    }

    /**
     * 是否达到循环打卡奖励
     *
     * @param userId
     * @return
     */
    public Engine isCycleNum(Long userId) {
        Integer num = cycleNum(userId);
        QueryWrapper<Engine> wrapper = new QueryWrapper<>();
        wrapper.eq("num", num);
        wrapper.eq("engine_type", EngineEnum.Cycle.getType());
        return engineService.getOne(wrapper, false);
    }

    public Integer getCycleRounds(Long userId) {
        Integer sumClock = sumClock(userId);
        return (sumClock / cycleDayNum) + 1;
    }
}
